/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package scriptedsands;

import java.awt.Image;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * Super class of all engines. An engine must be a subclass of this to work.
 * 
 * @author Dalton
 */
public abstract class AbstractEngine implements Runnable {
    protected int width = 512;
    protected int height = 512;
    protected BufferedImage bImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    protected boolean isPaused;
    protected boolean isDrawing;
    protected long fps;
    protected int penSize;
    protected int oldMouseX, oldMouseY, newMouseX, newMouseY;

    public AbstractEngine() {
    }

    /**
     * Starts running this in a new thread.
     */
    public void start() {
        Thread t = new Thread(this);
        t.start();
    }

    public final void run() {
        long beforeTime;
        long timeDiff;
        setup();
        while(true) {
            draw();
            if (!isPaused) {
                beforeTime = System.currentTimeMillis();
                step();
                timeDiff = System.currentTimeMillis() - beforeTime;
                fps = fps*4/5 + timeDiff/5;
            }
        }
    }

    /**
     * return approximate frames per second
     * @return
     */
    public long getFPS() {
        return 1000/(fps != 0 ? fps : 1);
    }
    
    public abstract void setup();

    /**
     * Put particles in sandbox at current mouse position.
     */
    public abstract void draw();

    /**
     * Method called each frame. Use this method to something each frame.
     */
    public abstract void step();

    /**
     * Set current element to e
     * @param e
     */
    public abstract void setElement(Object e);

    public final void drawing(boolean d) {
        isDrawing = d;
    }

    /**
     * Update mouse coordinates.
     * @param x mouse x position
     * @param y mouse y position
     */
    public final void updateMousePos(int x, int y) {
        oldMouseX = newMouseX;
        oldMouseY = newMouseY;
        newMouseX = x;
        newMouseY = y;
    }

    /**
     * Set pen size used to draw.
     * @param size
     */
    public void setPenSize(int size) {
        penSize = size;
    }

    /**
     * Returns true if coordinates are within the boundaries of the sandbox.
     * Returns false if not within sandbox boundaries.
     * @param x x coordinate
     * @param y y coordinate
     * @return
     */
    public final boolean withinSandboxBounds(int x, int y) {
        if (x >= 0 && y >= 0 && x < width && y < height)
            return true;
        return false;
    }

    /**
     * Get image to draw on screen
     * @return Image to draw on screen
     */
    public Image getImage() {
        return bImg;
    }
}
